/**
 * TabuListTest.java
 * ************************** 
 * @date May 12, 2011
 * @author Michele Tamburini
 * 
 * **************************
 */
package JUnitTests;

import static org.junit.Assert.*;

import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import gossipServices.basic.nodeDescriptors.ConcreteNodeDescriptor;
import gossipServices.basic.nodeDescriptors.NodeDescriptor;
import gossipServices.bootstraping.tman.tabuList.ConcreteTabuList;
import gossipServices.bootstraping.tman.tabuList.TabuList;

import org.junit.Before;
import org.junit.Test;

/**
 * Description: 
 *
 */
public class TabuListTest extends TestUtilFunctions {
	
	TabuList tabuList;
	int size = 5;

	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		tabuList = new ConcreteTabuList(size);
	}

	/**
	 * Test method for {@link gossipServices.bootstraping.tman.tabuList.ConcreteTabuList#ConcreteTabuList(int)}.
	 */
	@Test
	public void testConcreteTabuList() {
//		Deque queue = ((ConcreteTabuList) tabuList).getQueue();
		assertNotNull(tabuList);
		assertEquals(size, tabuList.getMaxSize());
//		fail("Not yet implemented");
	}

	/**
	 * Test method for {@link gossipServices.bootstraping.tman.tabuList.ConcreteTabuList#add(gossipServices.basic.nodeDescriptors.NodeDescriptor)}.
	 */
	@Test
	public void testAdd() {
		print("****************");
		print("TEST: add()");
		String addingNames[] = {"node1", "node2", "node3", "node5", "node6", "node7",
				"pippo", "node9", "brontolo", "dotto", "node2", "node10"};
		Vector<NodeDescriptor> vec = buildVector(addingNames);
		NodeDescriptor node;
		Deque<NodeDescriptor> queue;
		NodeDescriptor lastNode;
		
		int addingIndex = 0;
		int countAdded = 0;
		for(; addingIndex < size ; addingIndex++){
			node =vec.get(addingIndex);
			print("adding: "+node);
			tabuList.add(node);
			print("TabuList:\n"+tabuList);
			countAdded++;
			assertEquals(countAdded, tabuList.size());
			assertTrue(tabuList.contains(node));
		}
		queue = ((ConcreteTabuList)tabuList).getQueue();
		for(; addingIndex < vec.size(); addingIndex++){
			node = vec.get(addingIndex);
			lastNode = queue.getLast();
			print("adding: "+node);
			tabuList.add(node);
			countAdded++;
			print("TabuList:\n"+tabuList);
			// the TabuList size never exceeds the maxSize
			assertEquals(size, tabuList.size());
			// the last element now is discarded
			assertTrue(tabuList.contains(lastNode) == false);
			// the new element is correctly into the TabuList
			assertTrue(tabuList.contains(node));
			
			// Check the correct ordering of the element taking advantage of the vector
			// order must be in accordance with the reverse vector subset of 'size' elements
			Iterator<NodeDescriptor> tabuListIterator =queue.descendingIterator();
			List<NodeDescriptor> subVector = vec.subList(countAdded - size, countAdded);
			List<NodeDescriptor> tempVec = new Vector<NodeDescriptor>(size);
			while(tabuListIterator.hasNext()){
				tempVec.add(tabuListIterator.next());
			}
			assertEquals(subVector , tempVec);
		}
//		fail("Not yet implemented");
	}

	/**
	 * Test method for {@link gossipServices.bootstraping.tman.tabuList.ConcreteTabuList#boundSize(int)}.
	 */
	@Test
	public void testBoundSize() {
		String nodeString = "node";
		String name;
		boolean ret = tabuList.boundSize(size);
		assertTrue(ret);
		assertEquals(0, tabuList.size());
		int exagerateSize = 56;
		for(int i =0; i<size; i++)
			tabuList.add(new ConcreteNodeDescriptor(""));
		for(int i=0; i<exagerateSize; i++){
			name = nodeString + i;
			tabuList.add( new ConcreteNodeDescriptor(name));
			assertEquals(size, tabuList.size());
			tabuList.boundSize(size);
			assertEquals(size, tabuList.size());
		}
		
		// try to use and maintain an empty TabuList
		int zero = 0;
		TabuList zeroTabuList = new ConcreteTabuList(zero);
		assertNotNull(zeroTabuList);
		assertEquals(zero, zeroTabuList.getMaxSize());
		for(int i=0; i< exagerateSize; i++){
			zeroTabuList.add(new ConcreteNodeDescriptor(nodeString + i));
			assertEquals(zero, zeroTabuList.size());
		}
//		fail("Not yet implemented");
	}

	/**
	 * Test method for {@link gossipServices.bootstraping.tman.tabuList.ConcreteTabuList#contains(gossipServices.basic.nodeDescriptors.NodeDescriptor)}.
	 */
	@Test
	public void testContains() {
		// test with and empty TabuList:
		print("****************");
		print("TEST: contains()");
		boolean ret = tabuList.contains(new ConcreteNodeDescriptor("fake"));
		// don't explode!
		assertFalse(ret);
		print("testing and empty TabuList passed: "+(ret == false));
		
//		fail("Not yet implemented");
	}
	
}
